home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / tcop / fastpath.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  6.2 KB  |  248 lines

  1. /* ----------------------------------------------------------------
  2.  *   FILE
  3.  *    fastpath.c
  4.  *    
  5.  *   DESCRIPTION
  6.  *     routines to handle function requests from the frontend
  7.  *
  8.  *   INTERFACE ROUTINES
  9.  *    
  10.  *   NOTES
  11.  *    this protocol was hacked up quickly - should decide this
  12.  *    and then synchronize code in lib/libpq/{fe,be}-pqexec.c 
  13.  *
  14.  *    error condition may be asserted by fmgr code and
  15.  *       an "elog" propagated to the frontend independent of the
  16.  *       code in this module
  17.  *
  18.  *      for no good reason, function names are limited to 80 chars
  19.  *      by this module.
  20.  *    
  21.  *   IDENTIFICATION
  22.  *    $Header: /private/postgres/src/tcop/RCS/fastpath.c,v 1.15 1992/07/13 03:36:48 hong Exp $
  23.  * ----------------------------------------------------------------
  24.  */
  25.  
  26. #include "tmp/postgres.h"
  27.  
  28.  RcsId("$Header: /private/postgres/src/tcop/RCS/fastpath.c,v 1.15 1992/07/13 03:36:48 hong Exp $");
  29.  
  30. /* ----------------
  31.  *    FILE INCLUDE ORDER GUIDELINES
  32.  *
  33.  *    1) tcopdebug.h
  34.  *    2) various support files ("everything else")
  35.  *    3) node files
  36.  *    4) catalog/ files
  37.  *    5) execdefs.h and execmisc.h, if necessary.
  38.  *    6) extern files come last.
  39.  * ----------------
  40.  */
  41. #include "tcop/tcopdebug.h"
  42.  
  43. #include "utils/palloc.h"
  44. #include "utils/fmgr.h"
  45. #include "utils/log.h"
  46.  
  47. #include "catalog/syscache.h"
  48. #include "catalog/pg_type.h"
  49.  
  50. #include "tmp/fastpath.h"
  51.  
  52. /* ----------------
  53.  *    external_to_internal
  54.  * ----------------
  55.  */
  56. static int
  57. external_to_internal( string )
  58.      char *string;
  59. {
  60.     return((int)string);
  61. }
  62.  
  63. /* ----------------
  64.  *    internal_to_external
  65.  * ----------------
  66.  */
  67. static char * 
  68. internal_to_external( string )
  69.      char *string;
  70. {
  71.     return(string);
  72. }
  73.  
  74. /* ----------------
  75.  *    SendFunctionResult
  76.  * ----------------
  77.  */
  78. static void
  79. SendFunctionResult ( fid, retval, rettype )
  80.      int fid;
  81.      char *retval;
  82.      int rettype;
  83. {
  84.     char *retdata;
  85.  
  86. #if 0    
  87.     printf("Sending results %d, %d, %d",fid,retval,rettype);
  88. #endif    
  89.     
  90.     pq_putnchar("V",1);
  91.     pq_putint(fid,4);
  92.     
  93.     switch (rettype) {
  94.  
  95.       case 0:             /* void retval */
  96.         break;
  97.       case PORTAL_RESULT:
  98.     break;
  99.  
  100.       case VAR_LENGTH_RESULT:
  101.     retdata = internal_to_external(retval, MAX_STRING_LENGTH, 0);
  102.     pq_putnchar("G", 1);
  103.     pq_putint(rettype, 4);
  104.     pq_putstr(retdata);
  105.     break;
  106.  
  107.       case 1: case 2: case 4:
  108.     pq_putnchar("G",1);
  109.     pq_putint(rettype,4);
  110.     pq_putint(retval, rettype);
  111.     break;
  112.  
  113.       default:
  114.     pq_putnchar("G",1);
  115.     pq_putint(VARSIZE(retval)-4,4);
  116.     pq_putnchar(retval+4, VARSIZE(retval)-4);
  117.     }
  118.     pq_putnchar("0", 1);
  119.     pq_flush();
  120. } /* SendFunctionResult */
  121.  
  122. /* 
  123.     {
  124.     Datum sendproc;
  125.     bool attr_is_null;
  126.  
  127.     tuple = SearchSysCacheTuple (TYPOID,rettype);
  128.     if (HeapTupleIsValid(tuple)) {
  129.  
  130.  
  131.         sendproc = HeapTupleGetAttributeValue(tuple,
  132.                           InvalidBuffer,
  133.                           13,
  134.                           tupledesc,
  135.                           attr_is_null);
  136.                           
  137.         if ( RegProcedureIsValid ( sendproc )  == false )
  138.           elog(WARN,"invalid sending procedure");
  139.  
  140.     } */
  141.  
  142. /* ---------------
  143.  * 
  144.  * HandleFunctionRequest
  145.  * - externally callable routine for handling function requests
  146.  * 
  147.  * Desc : This code is called only when the backend recieves
  148.  *        a function request (current protocol is "F") we then
  149.  *        handle the parameters of the request here.
  150.  *        Requests come in 2 forms, by name, and by id.
  151.  *        If requests come by id, we just call the fmgr with the id
  152.  *        and the required number of arguments.
  153.  *        If requests come by name, we do a catalog lookup to determine
  154.  *        the id, which we subsequently return to the frontend so that
  155.  *        it may cache it , and subsequent calls to the same function
  156.  *        can be made by id.
  157.  *
  158.  *        XXX - note that if the catalog changes in the meantime, 
  159.  *              the function id cannot be invalidated here, and the
  160.  *              frontend must take care of it by itself  ( - jeff)
  161.  *      XXX - someday, maybe we should standardize on an RPC 
  162.  *        mechanism that everyone else uses
  163.  *
  164.  *        If any error condition exists, we terminate with an elog
  165.  *        which causes an "E" followed by the message to be sent to the
  166.  *        frontend.  
  167.  *
  168.  * BUGS:  for no particular reasion, function names are limited to 80
  169.  *        characters, and VARLENGTHARGS has a max of 100 (inherited from
  170.  *      the lisp backend)
  171.  * CAVEAT:the function_by_name code was given to me by Mike H, I am taking
  172.  *        it on faith since it looks ok & I don't have the time to verify it. 
  173.  *
  174.  * ----------------
  175.  */
  176.  
  177. int
  178. HandleFunctionRequest()
  179. {
  180.     int xactid;
  181.     int fid;
  182.     char function_name[MAX_FUNC_NAME_LENGTH+1];
  183.     char *retval;        /* XXX - should be datum, maybe ? */
  184.     int  arg[8];
  185.     int  arg_length[8];
  186.     int  rettype;
  187.     int  nargs;
  188.     int  i;
  189.     unsigned char palloced;
  190.  
  191.     xactid = pq_getint(4);
  192.     fid = pq_getint(4);
  193.     rettype = pq_getint(4);
  194.     nargs = pq_getint(4);
  195.  
  196.     /*
  197.      *  Copy arguments into arg vector.  If we palloc() an argument, we need
  198.      *  to remember, so that we pfree() it after the call.  Elsewhere, we
  199.      *  hardwire nargs <= 8, so palloced is an eight-bit flag vector.
  200.      */
  201.  
  202.     palloced = 0x0;
  203.     for (i = 0 ; i < nargs ; i++ ) {
  204.     arg_length[i] = pq_getint(4);
  205.     
  206.     if (arg_length[i] == VAR_LENGTH_ARG ) {
  207.         char *data = (char *) palloc(MAX_STRING_LENGTH);
  208.         palloced |= (1 << i);
  209.         pq_getstr(data,MAX_STRING_LENGTH);
  210.         arg[i] = external_to_internal(data,MAX_STRING_LENGTH,PASS_BY_REF);
  211.     } else if (arg_length[i] > 4)  {
  212.         char *vl;
  213. /*        elog(WARN,"arg_length of %dth argument too long",i);*/
  214.         vl = palloc(arg_length[i]);
  215.         palloced |= (1 << i);
  216.         VARSIZE(vl) = arg_length[i]+4;
  217.         pq_getnchar(VARDATA(vl),0,arg_length[i]);
  218.         arg[i] = (int)vl;
  219.     } else {
  220.         arg[i] = pq_getint ( arg_length[i]);
  221.     }
  222.     }
  223.  
  224.     /* lookup rettype in type catalog, and check send function */
  225.  
  226.     if (rettype == PORTAL_RESULT) {
  227.     /* fake it out by putting the stuff out first */
  228.     pq_putnchar("V",1);
  229.     pq_putint(0,4);
  230.     }
  231.  
  232. #if 0    
  233.     printf("\n arguments are %d %d %d \n",fid,arg[0],arg[1]);
  234.     printf("rettype = %d\n",rettype);
  235. #endif 
  236.     
  237.     retval = fmgr (fid, arg[0],arg[1],arg[2],arg[3],
  238.            arg[4],arg[5],arg[6],arg[7] );
  239.  
  240.     for (i = 0; i < nargs; i++) {
  241.     if (palloced & (1 << i))
  242.         pfree((Pointer)arg[i]);
  243.     }
  244.  
  245.     if (rettype != PORTAL_RESULT)
  246.     SendFunctionResult ( fid, retval, rettype );
  247. }
  248.